package httpx

import (
	"context"
	"fmt"
	"github.com/toolkits/pkg/errorx"
	"net/http"
	"time"
)

type HttpConfig struct {
	Host            string
	CertFile        string
	KeyFile         string
	Port            int
	ShutdownTimeout int
	ReadTimeout     int
	WriteTimeout    int
	IdleTimeout     int
}

func InitHttp(config HttpConfig, handler http.Handler) func() {
	srv := &http.Server{
		Addr:         fmt.Sprintf("%s:%d", config.Host, config.Port),
		Handler:      handler,
		ReadTimeout:  time.Duration(config.ReadTimeout) * time.Second,
		WriteTimeout: time.Duration(config.WriteTimeout) * time.Second,
		IdleTimeout:  time.Duration(config.IdleTimeout) * time.Second,
	}

	go func() {
		var err error
		if config.CertFile != "" {
			err = srv.ListenAndServeTLS(config.CertFile, config.KeyFile)
		} else {
			err = srv.ListenAndServe()
		}
		if err != nil && err != http.ErrServerClosed {
			errorx.Bomb(1, err.Error())
		}

	}()
	return func() {
		ctx, cancel := context.WithTimeout(context.Background(), time.Second*time.Duration(config.ShutdownTimeout))
		defer cancel()

		srv.SetKeepAlivesEnabled(false)

		err := srv.Shutdown(ctx)
		if err != nil {
			errorx.Bomb(1, err.Error())
		}

		select {
		case <-ctx.Done():
			println("http is exiting")
		default:
			println("serve is stopped")
		}
	}
}
